package com.example.market.service;

import com.example.market.exception.ExceptionEnum;
import com.example.market.exception.ServiceException;
import com.example.market.mapper.OrderMapper;
import com.example.market.mapper.ProductMapper;
import com.example.market.mapper.SeckillProductMapper;
import com.example.market.mapper.ShoppingCartMapper;
import com.example.market.pojo.Order;
import com.example.market.pojo.Product;
import com.example.market.pojo.SeckillProduct;
import com.example.market.pojo.ShoppingCart;
import com.example.market.util.IdWorker;
import com.example.market.vo.CartVo;
import com.example.market.vo.OrderVo;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderService {

    private IdWorker idWorker;
    private RedisTemplate redisTemplate;
    private OrderMapper orderMapper;
    private ShoppingCartMapper cartMapper;
    private ProductMapper productMapper;
    private SeckillProductMapper seckillProductMapper;
    private final static String SECKILL_PRODUCT_USER_LIST = "seckill:product:user:list";

    @Autowired
    public void setIdWorker(IdWorker idWorker) {
        this.idWorker = idWorker;
    }
    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    @Autowired
    public void setOrderMapper(OrderMapper orderMapper) {
        this.orderMapper = orderMapper;
    }
    @Autowired
    public void setCartMapper(ShoppingCartMapper cartMapper) {
        this.cartMapper = cartMapper;
    }
    @Autowired
    public void setProductMapper(ProductMapper productMapper) {
        this.productMapper = productMapper;
    }
    @Autowired
    public void setSeckillProductMapper(SeckillProductMapper seckillProductMapper) {
        this.seckillProductMapper = seckillProductMapper;
    }

    @Transactional
    public void addOrder(List<CartVo> cartVoList, Integer userId) {
        // 先添加订单
        String orderId = idWorker.nextId() + ""; // 订单id
        long time = new Date().getTime(); // 订单生成时间
        for (CartVo cartVo : cartVoList) {
            Order order = new Order();
            order.setOrderId(orderId);
            order.setOrderTime(time);
            order.setProductNum(cartVo.getNum());
            order.setProductId(cartVo.getProductId());
            order.setProductPrice(cartVo.getPrice());
            order.setUserId(userId);
            try {
                orderMapper.insert(order);
            } catch (Exception e) {
                e.printStackTrace();
                throw new ServiceException(ExceptionEnum.ADD_ORDER_ERROR);
            }
            // 减去商品库存,记录卖出商品数量
            // TODO : 此处会产生多线程问题，即不同用户同时对这个商品操作，此时会导致数量不一致问题
            Product product = productMapper.selectByPrimaryKey(cartVo.getProductId());
            product.setProductNum(product.getProductNum() - cartVo.getNum());
            product.setProductSales(product.getProductSales() + cartVo.getNum());
            productMapper.updateByPrimaryKey(product);
        }
        // 删除购物车
//        ShoppingCart cart = new ShoppingCart();
//        cart.setUserId(userId);
//        try {
//            int count = cartMapper.delete(cart);
//            if (count == 0) {
//                throw new ServiceException(ExceptionEnum.ADD_ORDER_ERROR);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new ServiceException(ExceptionEnum.ADD_ORDER_ERROR);
//        }
        ShoppingCart cart = new ShoppingCart();
        cart.setUserId(userId);
        for (CartVo cartVo : cartVoList){
            try {
                cart.setId(cartVo.getId());
                cartMapper.delete(cart);
            } catch (ServiceException e) {
                e.printStackTrace();
                throw new ServiceException(ExceptionEnum.DELETE_CART_ERROR);
            }
        }

    }

    public List<List<OrderVo>> getOrder(Integer userId) {
        List<OrderVo> list;
        ArrayList<List<OrderVo>> ret = new ArrayList<>();
        try {
            list = orderMapper.getOrderVoByUserId(userId);
            if (ArrayUtils.isEmpty(list.toArray())) {
                throw new ServiceException(ExceptionEnum.GET_ORDER_NOT_FOUND);
            }
            // 将同一个订单放在一组
            Map<String, List<OrderVo>> collect = list.stream().collect(Collectors.groupingBy(Order::getOrderId));
            Collection<List<OrderVo>> values = collect.values();
            ret.addAll(values);
        } catch (ServiceException e) {
            e.printStackTrace();
            throw new ServiceException(ExceptionEnum.GET_ORDER_ERROR);
        }
        return ret;
    }

    @Transactional
    public void addSeckillOrder(String seckillId, String userId) {
        // 订单id
        String orderId = idWorker.nextId() + "";
        // 商品id
        SeckillProduct seckillProduct = new SeckillProduct();
        seckillProduct.setSeckillId(Integer.parseInt(seckillId));
        SeckillProduct one = seckillProductMapper.selectOne(seckillProduct);
        Integer productId = one.getProductId();
        // 秒杀价格
        Double price = one.getSeckillPrice();

        // 订单封装
        Order order = new Order();
        order.setOrderId(orderId);
        order.setProductId(productId);
        order.setProductNum(1);
        order.setUserId(Integer.parseInt(userId));
        order.setOrderTime(new Date().getTime());
        order.setProductPrice(price);
        try {
            orderMapper.insert(order);
            // 减库存
            seckillProductMapper.decrStock(one.getSeckillId());
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(ExceptionEnum.ADD_ORDER_ERROR);
        }
        // 订单创建成功, 将用户写入redis, 防止多次抢购
        redisTemplate.opsForList().leftPush(SECKILL_PRODUCT_USER_LIST + seckillId, userId);
    }
}
